package com.wjk.kylin.mall.common.web.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.wjk.kylin.mall.common.core.constant.Constants;
import com.wjk.kylin.mall.common.core.enums.AuthenticationMethodEnum;
import lombok.SneakyThrows;
import org.apache.logging.log4j.util.Strings;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;

public class RequestUtil {

    public static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }

//    public static JSONObject getJwtPayload() {
//        String jwtPayload = getRequest().getHeader(Constants.JWT_PAYLOAD_KEY);
//        return JSONUtil.parseObj(jwtPayload);
//    }

//    public static Long getUserId() {
//        return getJwtPayload().getLong(Constants.USER_ID_KEY);
//    }
//
//    public static String getNickname() {
//        return getJwtPayload().getStr(Constants.NICK_NAME_KEY);
//    }
//
//    public static String getUsername() {
//        return getJwtPayload().getStr(Constants.USER_NAME_KEY);
//    }

    /**
     * 获取JWT的载体中的clientId
     *
     * @return
     */
//    public static String getClientId() {
//        return getJwtPayload().getStr(Constants.CLIENT_ID_KEY);
//    }
//
//    @SneakyThrows
//    public static String getGrantType() {
//        return getRequest().getParameter(Constants.GRANT_TYPE_KEY);
//    }


    /**
     * 获取登录认证的客户端ID
     * <p>
     * 兼容两种方式获取OAuth2客户端信息（client_id、client_secret）
     * 方式一：client_id、client_secret放在请求路径中
     * 方式二：放在请求头（Request Headers）中的Authorization字段，且经过加密，例如 Basic Y2xpZW50OnNlY3JldA== 明文等于 client:secret
     *
     * @return
     */
    @SneakyThrows
    public static String getOAuth2ClientId() {

        HttpServletRequest request = getRequest();

        // 从请求路径中获取
        String clientId = request.getParameter(Constants.CLIENT_ID_KEY);
        if (StrUtil.isNotBlank(clientId)) {
            return clientId;
        }

        // 从请求头获取
        String basic = request.getHeader(Constants.AUTHORIZATION_KEY);
        if (StrUtil.isNotBlank(basic) && basic.startsWith(Constants.BASIC_PREFIX)) {
            basic = basic.replace(Constants.BASIC_PREFIX, Strings.EMPTY);
            String basicPlainText = new String(Base64.getDecoder().decode(basic.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
            clientId = basicPlainText.split(":")[0]; //client:secret
        }
        return clientId;
    }

    /**
     * 解析JWT获取获取认证方式
     *
     * @return
     */
    @SneakyThrows
    public static String getAuthenticationMethod() {
        HttpServletRequest request = getRequest();
        String refreshToken = request.getParameter(Constants.REFRESH_TOKEN_KEY);

        String payload = StrUtil.toString(JWSObject.parse(refreshToken).getPayload());
        JSONObject jsonObject = JSONUtil.parseObj(payload);

        String authenticationMethod = jsonObject.getStr(Constants.AUTHENTICATION_METHOD);
        if (StrUtil.isBlank(authenticationMethod)) {
            authenticationMethod = AuthenticationMethodEnum.USERNAME.getValue();
        }
        return authenticationMethod;
    }
}
